<?php

/**
 * Pwiff - PHP SWF Library
 *
 * LICENSE
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @package    Pwiff
 * @subpackage Records
 * @copyright  Copyright (c) 2010 Steven Harris
 * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
 * @version    $Id: Rect.php 5 2010-02-14 05:08:39Z indigo.sunrise $
 */

/**
 * Represents a Rectangle record.
 *
 * @package    Pwiff
 * @subpackage Records
 */
class Pwiff_Record_Rect extends Pwiff_Record
{
	/**
	 * Minimum X coordinate.
	 * 
	 * @var int
	 */
	protected $xMin = 0;
	
	/**
	 * Maximum X coordinate.
	 *
	 * @var int
	 */
	protected $xMax = 0;
	
	/**
	 * Minimum Y coordinate.
	 *
	 * @var int
	 */
	protected $yMin = 0;
	
	/**
	 * Maximum Y coordinate.
	 *
	 * @var int
	 */
	protected $yMax = 0;
	
	/**
	 * Sets the minimum X value.
	 *
	 * @param  int $xMin
	 * @return Pwiff_Record_Rect
	 */
	public function setMinX($xMin)
	{
		$this->verifyCoordinate($xMin);
		$this->xMin = $xMin;
		return $this;
	}
	
	/**
	 * Sets the maximum X value.
	 * 
	 * @param  int $xMax
	 * @return Pwiff_Record_Rect
	 */
	public function setMaxX($xMax)
	{
		$this->verifyCoordinate($xMax);
		$this->xMax = $xMax;
		return $this;
	}
	
	/**
	 * Sets the minimum Y value.
	 * 
	 * @param  int $yMin
	 * @return Pwiff_Record_Rect
	 */
	public function setMinY($yMin)
	{
		$this->verifyCoordinate($yMin);
		$this->yMin = $yMin;
		return $this;
	}
	
	/**
	 * Sets the maximum Y value.
	 *
	 * @param  int $yMax
	 * @return Pwiff_Record_Rect
	 */
	public function setMaxY($yMax)
	{
		$this->verifyCoordinate($yMax);
		$this->yMax = $yMax;
		return $this;
	}
	
	/**
	 * Gets the minimum X value.
	 * 
	 * @return int
	 */
	public function getMinX()
	{
		return $this->xMin;
	}
	
	/**
	 * Gets the maximum X value.
	 *
	 * @return int
	 */
	public function getMaxX()
	{
		return $this->xMax;
	}
	
	/**
	 * Gets the minimum Y value.
	 *
	 * @return int
	 */
	public function getMinY()
	{
		return $this->yMin;
	}
	
	/**
	 * Gets the maximum Y value.
	 *
	 * @return int
	 */
	public function getMaxY()
	{
		return $this->yMax;
	}
	
	/**
	 * Gets the record length for this Rect.
	 *
	 * @return int
	 */
	public function getRecordLength()
	{
		// 5 for numBits, then four SB[numBits]
		$bits = 5 + ($this->getBitsNeeded() * 4);
		return ceil($bits / 8);
	}
	
	/**
	 * Writes the rectangle values to the given output instance.
	 *
	 * @param  Pwiff_Output $out
	 */
	public function write(Pwiff_Output $out)
	{
		$out->byteAlign(); // must be byte aligned
		
		$numBits = $this->getBitsNeeded();
		$out->writeBits($numBits, 5);
		$out->writeBits($this->xMin, $numBits);
		$out->writeBits($this->xMax, $numBits);
		$out->writeBits($this->yMin, $numBits);
		$out->writeBits($this->yMax, $numBits);
	}
	
	/**
	 * Verifies that the coordinate does not require more than 31 bits of
	 * storage, and throws an exception if it does.
	 *
	 * @param  int $coordinate
	 */
	protected function verifyCoordinate($coordinate)
	{
		if (!Pwiff_Util_Numerics::canFitSigned($coordinate, 31)) {
			throw new Pwiff_Exception('Coordinate out of range.');
		}
	}
	
	/**
	 * Returns the number of bits needed to store the coordinate values.
	 *
	 * @return int
	 */
	protected function getBitsNeeded()
	{
		return Pwiff_Util_Numerics::getSignedBitCount(
			array($this->xMin, $this->xMax, $this->yMin, $this->yMax));
	}
}
